package com.teamwings.modules.page.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.teamwings.common.constant.CommonConstant;
import com.teamwings.common.constant.FormConstant;
import com.teamwings.common.exception.ResultException;
import com.teamwings.common.jsqlparser.SelectParseHelper;
import com.teamwings.common.query.QueryGenerator;
import com.teamwings.common.vo.Result;
import com.teamwings.ctrls.FormComponent;
import com.teamwings.ctrls.entity.DatabaseTableWithColumns;
import com.teamwings.enums.ConstData;
import com.teamwings.modules.code.entity.FormTableCode;
import com.teamwings.modules.code.service.IFormTableCodeService;
import com.teamwings.modules.design.service.IDesignService;
import com.teamwings.modules.design.vo.FormVo;
import com.teamwings.modules.head.service.IFormTableHeadService;
import com.teamwings.modules.page.mapper.PageMapper;
import com.teamwings.modules.page.service.IPageService;
import com.teamwings.modules.page.vo.FormDataVo;
import com.teamwings.util.CtrlIsNumberByTypeUtil;
import com.teamwings.util.VoUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import net.sf.jsqlparser.JSQLParserException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author admin
 * @since 2021-05-07
 */
@RestController
@Api(tags = "表单实例管理")
@RequestMapping("/form/page")
public class PageController {

    @Autowired
    private IPageService pageService;

    @Autowired
    private IDesignService designService;

    @Autowired
    private IFormTableCodeService formTableCodeService;

    @Autowired
    private IFormTableHeadService formTableHeadService;
 @Autowired
    private PageMapper pageMapper;


    /**
     * 显示多条数据
     */
//    @ApiOperation(value = "根据form_id显示自定义表单数据", notes = "根据form_id显示自定义表单数据")
//    @GetMapping(value = "/list")
//    public Result<?> list(
//            @RequestParam(value = "formId") String formId,
//            @RequestParam(value = "pageNo", defaultValue = "1") Long pageNo,
//            @RequestParam(value = "pageSize", defaultValue = "20") Long pageSize
//    ) {
//        IPage<Map<String, String>> data = pageService.selectPageByRecords(formId, pageNo, pageSize);
//        return Result.OK("获取数据成功！", data);
//    }
    private List<String> getColumnByFormId(String formId) {
        String tableName = pageService.getTableNameById(formId);
        return pageService.getColumnByTableName(tableName);
    }

    /**
     * 参考查询过滤器用法 http://doc.jeecg.com/2043941
     * 显示多条数据
     */
    @ApiOperation(value = "根据form_id显示自定义表单列表数据", notes = "根据form_id显示自定义表单列表数据")
    @GetMapping(value = "/list")
    public Result<?> list(
            @RequestParam(value = "formId", required = false) String formId,
            @RequestParam(value = "pageNo", defaultValue = "1") Long pageNo,
            @RequestParam(value = "pageSize", defaultValue = "20") Long pageSize,
            @RequestParam(value = "fields", required = false) String fields,

            // logicTable用到的参数
            @RequestParam(value = "hasFormId", defaultValue = "true") Boolean hasFormId,
            @RequestParam(value = "key", required = false) String key,
            @RequestParam(value = "tableType", required = false) String tableType,
            @RequestParam(value = "formHeadId", required = false) String formHeadId,

            HttpServletRequest req
    ) {
        if (StringUtils.isNotEmpty(tableType) && tableType.equals(CommonConstant.LogicTableType.sql.getValue())) {
            return this.getLogicTablePage(pageNo, pageSize, hasFormId, key, tableType, formHeadId, req);
        }

        List<String> column = new ArrayList<>();
        // 如果有formId
        if (StringUtils.isNotEmpty(formId)) {
            column = this.getColumnByFormId(formId);
        }

        QueryWrapper<Object> queryWrapper = getQueryWrapperByQueryGenerator(formId, req, hasFormId);
        if (column.contains("FORM_STATE") || column.contains("form_state")) {
            queryWrapper.eq("form_state", 0);
        }
        IPage<Map<String, String>> page;

        if (StringUtils.isEmpty(formId)) {
            throw new ResultException("formId不能为空");
        }

        // 其他地方的查询，
        if (hasFormId) {
            page = pageService.selectPageByRecordsWithFields(formId, pageNo, pageSize, queryWrapper, fields);
        } else {
            page = pageService.selectPageByRecordsWithFields(formId, pageNo, pageSize, queryWrapper, fields, false);
        }

        return Result.OK("获取数据成功！", page);
    }

    private Result<IPage<Map<String, String>>> getLogicTablePage(Long pageNo, Long pageSize, Boolean hasFormId, String key, String tableType, String formHeadId, HttpServletRequest req) {
        // 如果是logicTable的sql模式 （ 这里不能通过前端传递sql，可能导致sql注入。）
        // 实例化表单设计，并表单设计里面拿到logicTable的sql查询语句
        String sql = getSqlByFormId(key, formHeadId);
        // 这里的field是jeecgboot默认的提供的
        String field = req.getParameter("field");
        //
        List<String> column = null;
        boolean hasWhere = false;
        boolean hasOrderBy = false;
        try {
            // 根据sql语句获取字段列表
            column = SelectParseHelper.getColumnBySql(pageService, sql);
            hasWhere = SelectParseHelper.hasWhere(pageService, sql);
            hasOrderBy = SelectParseHelper.hasOrderBy(pageService, sql);
        } catch (JSQLParserException e) {
            e.printStackTrace();
        }
//            ArrayList<String> fieldsArr = Lists.newArrayList(field.split(",")).stream().filter(StringUtils::isNotEmpty).collect(Collectors.toCollection(ArrayList::new));
        ArrayList<String> fieldsArr = new ArrayList<>(column);
        Map<String, String[]> parameterMap = req.getParameterMap();
        // 如果sql语句中已经包含order by了。那么逻辑表格中的order将不起作用
        if (hasOrderBy) {
            parameterMap = new HashMap(parameterMap);
            parameterMap.remove("order");
        }
        // 使用jeecgboot的查询构造器通过前端传递的参数生成queryWrapper
        QueryWrapper<Object> queryWrapper = getQueryWrapperByQueryGenerator(fieldsArr, req.getParameterMap(), hasFormId);
        if (column.contains("form_state") || column.contains("FORM_STATE")) {
            // logicTable需要判断是否有该字段
            queryWrapper.eq("form_state", 0);
        }
        // sql语句解析
        IPage<Map<String, String>> page = pageService.selectRecordsBySql(sql, pageNo, pageSize, queryWrapper, hasWhere);
        return Result.OK("获取数据成功！", page);
    }

    /**
     * 根据form_id获取字段和字段对应的类型
     */
    @ApiOperation(value = "根据form_id获取字段和字段对应的类型", notes = "根据form_id获取字段和字段对应的类型")
    @GetMapping(value = "/getColumnType/{formId}")
    public Result<?> getColumnType(
            @PathVariable("formId") String formId,
            @RequestParam(value = "hasFormId", required = false) Boolean hasFormId
    ) {
        Map<String, String> typeMap = formTableCodeService.getTypeMap(formId, hasFormId);
        return Result.OK("获取数据成功！", typeMap);
    }

    /**
     * 根据form_id获取字段和字段中文名
     */
    @ApiOperation(value = "根据form_id获取字段和字段中文名", notes = "根据form_id获取字段和字段中文名")
    @GetMapping(value = "/getColumnCname/{formId}")
    public Result<?> getColumnCname(@PathVariable("formId") String formId) {
        Map<String, String> typeMap = formTableCodeService.getCnameMap(formId);
        return Result.OK("获取数据成功！", typeMap);
    }

    /**
     * 根据查询构造器生成queryWrapper
     *
     * @param formId 自定义表单id
     * @param req    前端传过来的查询条件
     * @return QueryWrapper
     */
    private QueryWrapper<Object> getQueryWrapperByQueryGenerator(String formId, HttpServletRequest req) {
        FormTableCode entity = formTableCodeService.getLatestOneByFormId(formId);
        ArrayList<String> columns;
        if (entity == null) {
            columns = new ArrayList<>(pageService.getColumnByTableName(formId));
        } else {
            columns = Lists.newArrayList(entity.getTableFields().split(","));
        }
        this.addDefaultColumn(columns);
        Map<String, String> typeMap = formTableCodeService.getTypeMap(formId);
        return QueryGenerator.initQueryWrapper(columns, typeMap, req.getParameterMap());
    }

    private void addDefaultColumn(ArrayList<String> columns) {
        columns.add("ID");
        columns.add("FORM_ID");
        columns.add("FORM_VERSION");
        columns.add("FORM_CREATE_BY");
        columns.add("FORM_CREATE_TIME");
        columns.add("FORM_UPDATE_BY");
        columns.add("FORM_UPDATE_TIME");
    }

    /**
     * 根据查询构造器生成queryWrapper
     *
     * @param formId 自定义表单id
     * @param req    前端传过来的查询条件
     * @return QueryWrapper
     */
    private QueryWrapper<Object> getQueryWrapperByQueryGenerator(String formId, HttpServletRequest req, Boolean hasFormId) {
        if (hasFormId) {
            return this.getQueryWrapperByQueryGenerator(formId, req);
        }
        DatabaseTableWithColumns entity = designService.getTableWithColumns(formId);
        ArrayList<String> columns = Lists.newArrayList(entity.getColumns().split(","));
//        Map<String, String> typeMap = formTableCodeService.getTypeMap(formId);
        Map<String, String> typeMap = new HashMap<>();
        for (String column : columns) {
            typeMap.put(column, "text");
        }

        return QueryGenerator.initQueryWrapper(columns, typeMap, req.getParameterMap());
    }

    /**
     * 根据查询构造器生成queryWrapper
     *
     * @param req 前端传过来的查询条件
     * @return QueryWrapper
     */
    private QueryWrapper<Object> getQueryWrapperByQueryGenerator(ArrayList<String> columns, HttpServletRequest req, Boolean hasFormId) {
        Map<String, String> typeMap = new HashMap<>();
        for (String column : columns) {
            typeMap.put(column, "text");
        }
        return QueryGenerator.initQueryWrapper(columns, typeMap, req.getParameterMap());
    }

    /**
     * 根据查询构造器生成queryWrapper
     *
     * @param parameterMap 前端传过来的查询条件
     * @return QueryWrapper
     */
    private QueryWrapper<Object> getQueryWrapperByQueryGenerator(ArrayList<String> columns, Map<String, String[]> parameterMap, Boolean hasFormId) {
        Map<String, String> typeMap = new HashMap<>();
        for (String column : columns) {
            typeMap.put(column, "text");
        }
        return QueryGenerator.initQueryWrapper(columns, typeMap, parameterMap);
    }


    /**
     * 显示多条数据
     */
    @ApiOperation(value = "根据form_id显示自定义表单数据", notes = "根据form_id显示自定义表单数据")
    @GetMapping(value = "/allData")
    public Result<?> allData(@RequestParam(value = "formId") String formId) {
        List<Map<String, String>> allData = pageService.selectAllRecords(formId);
        return Result.OK("获取数据成功！", allData);
    }

    /**
     * 显示多条数据
     */
    @ApiOperation(value = "根据form_id显示自定义表单数据", notes = "根据form_id显示自定义表单数据")
    @GetMapping(value = "/columnAndList")
    public Result<?> columnAndList(
            HttpServletRequest request,
            @RequestParam(value = "formId") String formId,
            @RequestParam(value = "page", defaultValue = "1") Long page,
            @RequestParam(value = "pageSize", defaultValue = "20") Long pageSize
    ) {
        // 查询表单有什么字段
        List<Map<String, String>> column = formTableCodeService.getColumn(formId);
        QueryWrapper<?> queryWrapper = makeConditionQuery(request, column);
        IPage<Map<String, String>> data = pageService.selectPageByRecords(formId, page, pageSize, queryWrapper);



        Map<String, Object> map = new HashMap<>();
        map.put("column", column);
        map.put("data", data);
        return Result.OK("获取数据成功！", map);
    }

    /**
     * 根据form_id 获取table_code
     */
    @ApiOperation(value = "根据form_id 获取table_code", notes = "根据form_id 获取table_code")
    @GetMapping(value = "/tableCode/{form_id}")
    public Result<?> tableCode(
            @PathVariable("form_id") String formId
    ) {
        String tableCode = pageService.getTableCodeBy(formId, null);
        FormVo data = VoUtils.newFormVo(tableCode);
        return Result.OK("获取数据成功！", data);
    }

    /**
     * 根据form_id 获取table_code
     */
    @ApiOperation(value = "根据form_id 获取table_code", notes = "根据form_id 获取table_code")
    @GetMapping(value = "/getAllTableCode")
    public Result<?> getAllTableCode(
            @RequestParam("headId") String headId
    ) {
        List<FormTableCode> list = pageService.getTableCodeVersionByHeadId(headId);
        return Result.OK("获取数据成功！", list);
    }


    /**
     * 显示一条数据
     * 因为有控件事件，这个接口不做缓存，缓存放到 pageService里面
     * TODO
     * 控件事件可优化成异步
     */
    @ApiOperation(value = "根据form_id,id显示自定义表单对应的数据", notes = "根据form_id,id显示自定义表单对应的数据")
    @GetMapping(value = {"/show/{form_id}/{id}", "/show/{form_id}/{id}/{version}"})
    public Result<?> show(
            @PathVariable("form_id") String formId,
            @PathVariable("id") String id,
            @PathVariable(value = "version", required = false) String version
    ) {
        Map<String, Object> data = pageService.show(formId, id);
        // 2022-01-22 show接口只返回表单实例数据
        // String tableCode;
        // if (data == null) {
        //     if (StringUtils.isNotEmpty(version)) {
        //         tableCode = pageService.getTableCodeBy(formId,Integer.parseInt(version));
        //     } else {
        //         FormTableCode formTableCode = formTableCodeService.getLatestOneByFormId(formId);
        //         tableCode = formTableCode.getTableCode();
        //     }
        // } else {
        //     if (StringUtils.isEmpty(version)) {
        //         version = data.get("form_version").toString();
        //     }
        //     tableCode = pageService.getTableCodeBy(formId, Integer.parseInt(version));
        // }

        // FormVo design = VoUtils.newFormVo(tableCode);

        Map<String, Object> map = new HashMap<>(2);
        // map.put("design", tableCode);
        map.put("data", data);
        // 2022-01-22 取消服务端的显示触发事件，改由前端自己控制，减轻服务端负担
        // 同步触发控件
        // try {
        //     // 查找可以触发条件的控件类型
        //     FieldsLoopUtil.loop(design.getList(), formComponent -> {
        //         if (ArrayUtils.indexOf(FormConstant.FORM_TRIGGER_SHOW, formComponent.getType()) > -1) {
        //             formComponent.trigger(FormConstant.TRIGGER_TYPE.PAGE_SHOW, pageService, design, data);
        //         }
        //     });
        // } catch (Exception e) {
        //     e.printStackTrace();
        // }
        return Result.OK("获取数据成功！", map);
    }

    /**
     * 显示一条数据
     */
//    @ApiOperation(value = "根据form_id,id显示自定义表单对应的数据", notes = "根据form_id,id显示自定义表单对应的数据")
//    @GetMapping(value = "/view/{form_id}/{id}")
//    public Result<?> view(
//            @PathVariable("form_id") String formId,
//            @PathVariable("id") String id
//    ) {
//        Map<String, String> data = pageService.show(formId, id);
//        return Result.OK("获取数据成功！", data);
//    }


//    @ApiOperation(value = "根据form_id添加一条数据", notes = "根据form_id添加一条数据")
//    @PostMapping(value = "/add")
//    public Result<?> add(@RequestBody FormDataVo formDataVo) {
//        String instanceId = pageService.add(formDataVo);
//        return Result.OK("添加数据成功！", instanceId);
//    }
    @ApiOperation(value = "根据form_id添加一条数据", notes = "根据form_id添加一条数据")
    @PostMapping(value = "/add")
    public Result<?> add(HttpServletRequest httpServletRequest) {
        String mapValueStr = httpServletRequest.getParameter("map");
        String formId = httpServletRequest.getParameter("formId");
        JSONObject jsonObject = JSON.parseObject(mapValueStr);
        Map<String, Object> map = jsonObject.getInnerMap();
        HashMap<String, String> hashMap = new HashMap<>();
        for (String key : map.keySet()) {
            hashMap.put(key, String.valueOf(map.get(key)));
        }
        FormDataVo formDataVo = new FormDataVo();
        Map<String, Object> t = JSONObject.parseObject(JSON.toJSONString(hashMap), new TypeReference<Map<String, Object>>() {
        });
        formDataVo.setMap(t);
        formDataVo.setFormId(formId);
        String instanceId = pageService.add(formDataVo);
        return Result.OK(instanceId);
    }

    /**
     *
     */
    @ApiOperation(value = "根据表单设计ID和表单实例ID删除一条数据",
            notes = "根据formHeadId和formInstId删除一条数据")
    @PostMapping(value = "/remove/{formHeadId}/{formInstId}")
    public Result<?> remove(
            @PathVariable("formHeadId") String formHeadId,
            @PathVariable("formInstId") String formInstId
    ) {
        pageService.remove(formHeadId, formInstId);
        return Result.OK("删除数据成功！");
    }

    /**
     *
     */
    @CacheEvict(value = FormConstant.FORM_PAGE_SHOW, key = "#formDataVo.map['ID'].toString()")
    @ApiOperation(value = "根据form_id编辑一条数据", notes = "根据form_id编辑一条数据")
    @PostMapping(value = "/edit")
    public Result<?> edit(@RequestBody FormDataVo formDataVo) {
        pageService.edit(formDataVo);
        return Result.OK("更新数据成功！");
    }


    /**
     * 把接收到的参数转化为条件
     * 默认只查询 form_state != 3的数据
     */
    public QueryWrapper<?> makeConditionQuery(HttpServletRequest request, List<Map<String, String>> column) {
        String conditions = request.getParameter("conditions");
        // 处理字段条件
        /*
        conditions: {
            condition: [{
                condition: '=', // '>', '>=', 'like'
                field: 'input_1623137725358'
                id: 'e8787ded-a3e4-4788-aec5-a66d9192cd6c'
            }],
            table: [{
                key: 'input_1623137725358',
                label: '姓名'
            }]
        }
         */
        QueryWrapper<?> queryWrapper = new QueryWrapper<>();

        // 记录设置过的字段名
        Set<String> fieldNames = new TreeSet(String.CASE_INSENSITIVE_ORDER);

        if (conditions != null && !conditions.equals("")) {
            try {
                conditions = java.net.URLDecoder.decode(conditions, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            JSONObject jsonObject = JSON.parseObject(conditions);
            JSONArray jaCondition = jsonObject.getJSONArray("condition");

            jaCondition.forEach((ja) -> {
                JSONObject condition = (JSONObject) ja;
                // 字段名
                final String field = condition.getString("field");
                fieldNames.add(field);

                // 参数ID，提交上来的参数会以这个值做参数名称
                String idParam = condition.getString("id");
//                idParam = idParam.replace("-", "_");
                // 检查是否有提交这个查询参数
//                String fieldParam = request.getParameter(field);
                String fieldParam = request.getParameter(idParam);
                if (fieldParam != null && !"".equals(fieldParam)) {
                    try {
                        fieldParam = URLDecoder.decode(fieldParam, "utf-8");
                        System.out.println("自动查询列表接收参数：" + fieldParam);
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    // 比较运算符
                    String operator = condition.getString("condition");
                    String ctrl = condition.getString("ctrl");
//                    if ("like".equals(operator)) {
//                        fieldParam = "%" + fieldParam + "%";
//                    }

                    // 查找表中实际的类型
                    Optional<Map<String, String>> optional = column.stream().filter(c -> c.get("key").equals(field)).findAny();
                    if (!optional.isPresent()) {
                        return;
                    }
                    String columnType = optional.get().get("type");
                    boolean beNumber = CtrlIsNumberByTypeUtil.isNumber(columnType);
                    Integer fieldParamNumber = beNumber ? Integer.valueOf(fieldParam) : null;
                    // 字段名大小写指定
                    String fieldDb = "\"" + field + "\"";
                    // 时间区间判断
                    if (ctrl.equals("range-picker")) {
                        String[] betweenDate = fieldParam.split(",");
                        String startDate = betweenDate[0];
                        String endDate = betweenDate[1];
                        queryWrapper.ge(fieldDb, startDate);
                        queryWrapper.le(fieldDb, endDate);
                    } else {
                        // 一般判断
                        switch (operator) {
                            case "=":
                                queryWrapper.eq(fieldDb, beNumber ? fieldParamNumber : fieldParam);
                                break;
                            case "like":
                                queryWrapper.like(fieldDb, fieldParam);
                                break;
                            case "<>":
                                queryWrapper.ne(fieldDb, beNumber ? fieldParamNumber : fieldParam);
                                break;
                            case ">":
                                queryWrapper.gt(fieldDb, beNumber ? fieldParamNumber : fieldParam);
                                break;
                            case ">=":
                                queryWrapper.ge(fieldDb, beNumber ? fieldParamNumber : fieldParam);
                                break;
                            case "<":
                                queryWrapper.lt(fieldDb, beNumber ? fieldParamNumber : fieldParam);
                                break;
                            case "<=":
                                queryWrapper.le(fieldDb, beNumber ? fieldParamNumber : fieldParam);
                                break;
                            default:
                                break;
                        }
                    }
                }
            });
        }

        if (!fieldNames.contains("form_state")) {
            // 等同于 AND (form_state IS NULL OR form_state <> 3)
            // 处理冲突，此处代码和冲突代码一致。
            queryWrapper.and((query) -> {
                query.isNull("form_state")
                        .or().ne("form_state", ConstData.RECORD_STATE_DELETE);
            });
        }

        return queryWrapper;
    }

    /**
     * 检测某个表某个字段的值是否有值 (需要排除本条数据)
     */
    @ApiOperation(value = "检测某个表某个字段的值是否有值 (需要排除本条数据)", notes = "检测某个表某个字段的值是否有值 (需要排除本条数据)")
    @GetMapping(value = "/repeat")
    public Result<?> repeat(
            @RequestParam(value = "form_id") String formId,
            @RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "field") String field,
            @RequestParam(value = "value") String value
    ) {
        Boolean b = pageService.repeat(formId, id, field, value);
        return Result.OK(b);
    }

    /**
     * 参考查询过滤器用法 http://doc.jeecg.com/2043941
     * 显示多条数据
     */
    @SneakyThrows
    @ApiOperation(value = "根据form_id显示自定义表单列表数据", notes = "根据form_id显示自定义表单列表数据")
    @GetMapping(value = "/all")
    public Result<?> all(
            @RequestParam(value = "formId", required = false) String formId,
            @RequestParam(value = "fields", required = false) String fields,
            @RequestParam(value = "hasFormId", defaultValue = "true") Boolean hasFormId,
            @RequestParam(value = "key", required = false) String key,
            @RequestParam(value = "tableType", required = false) String tableType,
            @RequestParam(value = "formHeadId", required = false) String formHeadId,
            HttpServletRequest req
    ) {
        if (StringUtils.isNotEmpty(tableType) && tableType.equals(CommonConstant.LogicTableType.sql.getValue())) {
            // 处理逻辑表格sql模式
            return this.getLogicTableList(hasFormId, key, tableType, formHeadId, req);
        }

        List<String> column = new ArrayList<>();
        // 如果有formId
        if (StringUtils.isNotEmpty(formId)) {
            column = this.getColumnByFormId(formId);
        }

        QueryWrapper<Object> queryWrapper = getQueryWrapperByQueryGenerator(formId, req, hasFormId);
        if (column.contains("FORM_STATE") || column.contains("form_state")) {
            queryWrapper.eq("form_state", 0);
        }

        if (StringUtils.isEmpty(formId)) {
            throw new ResultException("formId不能为空");
        }
        // todo 用column对fields进行过滤
        String tableName = formTableHeadService.getTableNameById(formId);
        List<Map> res = pageService.selectFields2(fields, tableName, queryWrapper);
        return Result.OK("获取数据成功！", res);
    }

    private Result<List<Map<String, Object>>> getLogicTableList(Boolean hasFormId, String key, String tableType, String formHeadId, HttpServletRequest req) throws JSQLParserException {
        // 实例化表单设计，并表单设计里面拿到logicTable的sql查询语句
        String sql = getSqlByFormId(key, formHeadId);
        // 这里的field是jeecgboot默认的提供的
        String field = req.getParameter("field");

        List<String> column = SelectParseHelper.getColumnBySql(pageService, sql);
        boolean hasWhere =  SelectParseHelper.hasWhere(pageService, sql);
        boolean hasOrderBy =  SelectParseHelper.hasOrderBy(pageService, sql);

        ArrayList<String> fieldsArr = new ArrayList<>(column);
        Map<String, String[]> parameterMap = req.getParameterMap();
        // 如果sql语句中已经包含order by了。那么逻辑表格中的order将不起作用
        if (hasOrderBy) {
            parameterMap = new HashMap(parameterMap);
            parameterMap.remove("order");
        }
        // 使用jeecgboot的查询构造器通过前端传递的参数生成queryWrapper
        QueryWrapper<Object> queryWrapper = getQueryWrapperByQueryGenerator(fieldsArr, req.getParameterMap(), hasFormId);
        if (column.contains("form_state") || column.contains("FORM_STATE")) {
            // logicTable需要判断是否有该字段
            queryWrapper.eq("form_state", 0);
        }

        List<Map<String, Object>> res = pageMapper.selectBySql(sql, queryWrapper, hasWhere);
        return Result.OK("获取数据成功！", res);
    }


    private String getSqlByFormId(String key, String formHeadId) {
        LambdaQueryWrapper<FormTableCode> codeQueryWrapper = new LambdaQueryWrapper<>();
        codeQueryWrapper.eq(FormTableCode::getTableHeadId, formHeadId);
        codeQueryWrapper.orderByDesc(FormTableCode::getTableVersion);
        codeQueryWrapper.last("limit 1");
        FormTableCode code = formTableCodeService.getOne(codeQueryWrapper);

        String tableCode = code.getTableCode();
        FormVo formVo = VoUtils.newFormVoAllowNoField(tableCode);
        List<FormComponent> formComponentList = formVo.getList();
        String sql = "";

        // 和jeecgboot生成的查询构造器的sql语句进行拼接
        for (FormComponent formComponent : formComponentList) {
            // 后期这里需要缓存一下，logicTable的key对应那个sql，这样不需要每次查询的时候促发一次table_code转formVo
            if (formComponent.getKey().equals(key)) {
                Map<String, Object> options = formComponent.getOptions();
                sql = String.valueOf(options.get("sql"));
                break;
            }
        }
        return sql;
    }

}



